package com.ng.common.component.engine.parser;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;

import com.ng.common.component.engine.enums.CompareOperator;

/**
 * 增强型条件判断工具类
 * 提供高性能的数值比较和复杂运算功能，支持多种数据类型和运算符
 * 
 * 主要功能：
 * 1. 通用数值比较（支持整数、浮点数、大数等）
 * 2. 高精度数学运算（加、减、乘、除、幂等）
 * 3. 复杂逻辑运算（AND、OR、XOR、NAND、NOR）
 * 4. 自定义比较逻辑
 * 
 * 特点：
 * - 线程安全
 * - 高性能（使用缓存和优化的算法）
 * - 精确计算（使用BigDecimal处理高精度计算）
 */
public final class EnhancedConditionJudgment {
	
	/** 数值计算精度控制，保留10位小数，使用四舍五入 */
	private static final MathContext MC = new MathContext(10, RoundingMode.HALF_UP);
	/** 浮点数比较的误差范围 */
	private static final double EPSILON = 1e-10;
	
	/**
	 * 私有构造函数防止实例化
	 * 该类只提供静态方法，不应被实例化
	 */
	private EnhancedConditionJudgment() {
		throw new AssertionError("Utility class should not be instantiated");
	}

	/**
	 * 通用数值比较方法，支持不同数值类型的比较操作
	 * 对于浮点数采用误差范围比较，避免精度问题
	 * 对于其他数值类型使用自然顺序比较
	 *
	 * @param <T> 数值类型，必须是Number的子类且实现Comparable接口
	 * @param a 第一个比较值
	 * @param b 第二个比较值
	 * @param operator 比较运算符
	 * @return 比较结果
	 * @throws IllegalArgumentException 当比较值为null或运算符无效时
	 */
	public static <T extends Number & Comparable<T>> boolean compare(T a, T b, CompareOperator operator) {
		if (a == null || b == null) {
			throw new IllegalArgumentException("Comparison values cannot be null");
		}

		// 处理浮点数比较的特殊情况
		if (a instanceof Double || a instanceof Float) {
			double diff = a.doubleValue() - b.doubleValue();
			switch (operator) {
			case EQUALS:
				return Math.abs(diff) < EPSILON;
			case NOT_EQUALS:
				return Math.abs(diff) >= EPSILON;
			case GREATER_THAN:
				return diff > EPSILON;
			case LESS_THAN:
				return diff < -EPSILON;
			case GREATER_OR_EQUAL:
				return diff > -EPSILON;
			case LESS_OR_EQUAL:
				return diff < EPSILON;
			default:
				throw new IllegalArgumentException("Invalid operator");
			}
		}

		// 其他数值类型的比较
		int comparison = a.compareTo(b);
		switch (operator) {
		case EQUALS:
			return comparison == 0;
		case NOT_EQUALS:
			return comparison != 0;
		case GREATER_THAN:
			return comparison > 0;
		case LESS_THAN:
			return comparison < 0;
		case GREATER_OR_EQUAL:
			return comparison >= 0;
		case LESS_OR_EQUAL:
			return comparison <= 0;
		default:
			throw new IllegalArgumentException("Invalid operator");
		}
	}

	/**
	 * 高精度数学运算工具类
	 * 使用BigDecimal进行精确计算，避免浮点数精度问题
	 * 实现了数值的缓存机制，提高性能
	 */
	public static class MathOperations {
		/** 缓存常用的BigDecimal值，提高性能 */
		private static final ConcurrentHashMap<Integer, BigDecimal> DECIMAL_CACHE = new ConcurrentHashMap<>();
		
		/**
		 * 高精度加法
		 * @param a 第一个操作数
		 * @param b 第二个操作数
		 * @return 计算结果
		 */
		public static BigDecimal add(Number a, Number b) {
			return toBigDecimal(a).add(toBigDecimal(b), MC);
		}
		
		public static BigDecimal subtract(Number a, Number b) {
			return toBigDecimal(a).subtract(toBigDecimal(b), MC);
		}
		
		public static BigDecimal multiply(Number a, Number b) {
			return toBigDecimal(a).multiply(toBigDecimal(b), MC);
		}
		
		public static BigDecimal divide(Number a, Number b) {
			BigDecimal divisor = toBigDecimal(b);
			if (divisor.compareTo(BigDecimal.ZERO) == 0) {
				throw new ArithmeticException("Division by zero");
			}
			return toBigDecimal(a).divide(divisor, MC);
		}
		
		public static BigDecimal modulo(Number a, Number b) {
			BigDecimal divisor = toBigDecimal(b);
			if (divisor.compareTo(BigDecimal.ZERO) == 0) {
				throw new ArithmeticException("Division by zero");
			}
			return toBigDecimal(a).remainder(divisor, MC);
		}
		
		public static BigDecimal power(Number base, Number exponent) {
			BigDecimal result = toBigDecimal(base).pow(exponent.intValue(), MC);
			return result.stripTrailingZeros();
		}
		
		/**
		 * 将Number类型转换为BigDecimal
		 * 优先使用缓存中的值，提高性能
		 *
		 * @param number 要转换的数值
		 * @return BigDecimal实例
		 */
		private static BigDecimal toBigDecimal(Number number) {
			if (number instanceof BigDecimal) {
				return (BigDecimal) number;
			}
			if (number instanceof Integer) {
				return DECIMAL_CACHE.computeIfAbsent(number.intValue(), 
					k -> new BigDecimal(k, MC));
			}
			return new BigDecimal(number.toString(), MC);
		}
	}

	/**
	 * 逻辑运算枚举
	 * 定义了各种逻辑运算的实现，支持短路运算
	 * 每个运算符都包含其运算规则的实现
	 */
	public enum LogicalOperator {
		/** 逻辑与运算，所有条件为true时返回true */
		AND((conditions, index) -> {
			for (int i = index; i < conditions.size(); i++) {
				if (!conditions.get(i)) return false; // 短路运算
			}
			return true;
		}),
		
		/** 逻辑或运算，任一条件为true时返回true */
		OR((conditions, index) -> {
			for (int i = index; i < conditions.size(); i++) {
				if (conditions.get(i)) return true; // 短路运算
			}
			return false;
		}),
		
		/** 异或运算，结果为true的条件数量为奇数时返回true */
		XOR((conditions, index) -> {
			boolean result = conditions.get(index);
			for (int i = index + 1; i < conditions.size(); i++) {
				result ^= conditions.get(i);
			}
			return result;
		}),
		
		/** 与非运算，对AND结果取反 */
		NAND((conditions, index) -> !AND.evaluate(conditions, index)),
		
		/** 或非运算，对OR结果取反 */
		NOR((conditions, index) -> !OR.evaluate(conditions, index));

		private final BiFunction<List<Boolean>, Integer, Boolean> evaluator;

		LogicalOperator(BiFunction<List<Boolean>, Integer, Boolean> evaluator) {
			this.evaluator = evaluator;
		}

		/**
		 * 执行逻辑运算
		 * @param conditions 条件列表
		 * @param startIndex 开始位置
		 * @return 运算结果
		 */
		public boolean evaluate(List<Boolean> conditions, int startIndex) {
			return evaluator.apply(conditions, startIndex);
		}
	}

	/**
	 * 组合多个条件进行逻辑运算
	 * 支持短路运算，提高性能
	 *
	 * @param conditions 条件列表
	 * @param operator 逻辑运算符
	 * @return 运算结果
	 * @throws IllegalArgumentException 当条件列表为空时
	 */
	public static boolean combineConditions(List<Boolean> conditions, LogicalOperator operator) {
		if (conditions == null || conditions.isEmpty()) {
			throw new IllegalArgumentException("Conditions list cannot be null or empty");
		}
		return operator.evaluate(conditions, 0);
	}

	/**
	 * 条件表达式求值
	 * 支持自定义比较逻辑和标准比较操作
	 *
	 * @param value1 第一个值
	 * @param value2 第二个值
	 * @param compareOp 比较运算符
	 * @param customPredicate 自定义比较逻辑（可选）
	 * @return 比较结果
	 */
	public static boolean evaluateCondition(
			Number value1,
			Number value2,
			CompareOperator compareOp,
			BiPredicate<Number, Number> customPredicate) {
		
		if (customPredicate != null) {
			return customPredicate.test(value1, value2);
		}
		
		// 将 Number 转换为 Double 进行比较
		Double v1 = value1.doubleValue();
		Double v2 = value2.doubleValue();
		return compare(v1, v2, compareOp);
	}

	// 便捷比较方法，提供常用的比较操作
	public static <T extends Number & Comparable<T>> boolean isEqual(T a, T b) {
		return compare(a, b, CompareOperator.EQUALS);
	}

	public static <T extends Number & Comparable<T>> boolean isGreaterThan(T a, T b) {
		return compare(a, b, CompareOperator.GREATER_THAN);
	}

	public static <T extends Number & Comparable<T>> boolean isLessThan(T a, T b) {
		return compare(a, b, CompareOperator.LESS_THAN);
	}

	public static void main(String[] args) {
		// 测试整数比较
		System.out.println(compare(Double.valueOf(5), Double.valueOf(3), CompareOperator.GREATER_THAN)); // true

		// 测试浮点数比较
		System.out.println(compare(2.5, 3.1, CompareOperator.LESS_THAN)); // true

		// 测试长整数比较
		System.out.println(compare(Double.valueOf(100), Double.valueOf(200), CompareOperator.LESS_OR_EQUAL)); // true

		// 测试数学运算
		System.out.println(MathOperations.modulo(10, 3)); // 1
		System.out.println(MathOperations.power(2, 3)); // 8.0

		// 测试逻辑组合
		List<Boolean> conditions = new ArrayList<>();
		conditions.add(evaluateCondition(5, 3, CompareOperator.GREATER_THAN, null)); // true
		conditions.add(evaluateCondition(4, 5, CompareOperator.LESS_THAN, null)); // true
		System.out.println(combineConditions(conditions, LogicalOperator.AND)); // true

		conditions.clear();
		conditions.add(evaluateCondition(5, 10, CompareOperator.EQUALS, null)); // false
		conditions.add(evaluateCondition(7, 8, CompareOperator.GREATER_THAN, null)); // false
		System.out.println(combineConditions(conditions, LogicalOperator.OR)); // false

		// 测试自定义比较逻辑
		System.out.println(evaluateCondition(5, 2, CompareOperator.GREATER_THAN,
			(a, b) -> a.doubleValue() > b.doubleValue() * 2)); // true

		// 测试 NAND 和 NOR 操作
		conditions.clear();
		conditions.add(true);
		conditions.add(true);
		System.out.println("NAND result: " + combineConditions(conditions, LogicalOperator.NAND)); // false
		System.out.println("NOR result: " + combineConditions(conditions, LogicalOperator.NOR)); // false
	}
}